package com.spot.workflow.controller;

import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.engine.*;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.image.ProcessDiagramGenerator;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@Slf4j
@RequestMapping("/flow")
public class HelloFlowable {

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private ProcessEngine processEngine;


    @GetMapping("/startflow")
    public String startFLow() {
        log.info("start flow");
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("taskUser", "123");
            ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("hello", params);
            return processInstance.getId();
        } catch (Exception e) {
            log.error("流程启动异常：{}", e, e.getStackTrace());
        }
        return "";
    }

    @GetMapping("/getTask")
    public String getTask() {
        log.info("getTask");
        try {
            Task task = taskService.createTaskQuery().singleResult();
            taskService.complete(task.getId());
            return task.getId();
        } catch (Exception e) {
            log.error("获取task异常：{}", e, e.getStackTrace());
        }
        return "";
    }

    /**
     * 获取审批管理列表
     */
    @RequestMapping(value = "/list")
    public Object list() {
        List<Task> tasks = taskService.createTaskQuery().taskAssignee("123").orderByTaskCreateTime().desc().list();
        for (Task task : tasks) {
            System.out.println(task.toString());
        }
        return tasks.toString();
    }

    /**
     * 获取审批通过
     */
    @RequestMapping(value = "/apply")
    public String apply() {
        List<Task> tasks = taskService.createTaskQuery().taskAssignee("123").orderByTaskCreateTime().desc().list();
        for (Task task : tasks) {
            Map<String,Object> params=new HashMap<>();
            params.put("pass",true);
            taskService.complete(task.getId(),params);
        }
        return tasks.toString();
    }


    /**
     * 生成流程图
     *
     * @param processId 任务ID
     */
    @RequestMapping(value = "processDiagram")
    public void genProcessDiagram(HttpServletResponse httpServletResponse, String processId) throws Exception {
        ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId("32505").singleResult();

        //流程走完的不显示图
        if (pi == null) {
            return;
        }
        try {
            Task task = taskService.createTaskQuery().processInstanceId(pi.getId()).singleResult();
            //使用流程实例ID，查询正在执行的执行对象表，返回流程实例对象
            String InstanceId = task.getProcessInstanceId();
            List<Execution> executions = runtimeService
                    .createExecutionQuery()
                    .processInstanceId(InstanceId)
                    .list();

            //得到正在执行的Activity的Id
            List<String> activityIds = new ArrayList<>();
            List<String> flows = new ArrayList<>();
            for (Execution exe : executions) {
                List<String> ids = runtimeService.getActiveActivityIds(exe.getId());
                activityIds.addAll(ids);
            }

            //获取流程图
            BpmnModel bpmnModel = repositoryService.getBpmnModel(pi.getProcessDefinitionId());
            ProcessEngineConfiguration engconf = processEngine.getProcessEngineConfiguration();
            ProcessDiagramGenerator diagramGenerator = engconf.getProcessDiagramGenerator();
            InputStream in = diagramGenerator.generateDiagram(bpmnModel, "png", activityIds, flows, engconf.getActivityFontName(), engconf.getLabelFontName(), engconf.getAnnotationFontName(), engconf.getClassLoader(), 1.0);
            OutputStream out = null;
            byte[] buf = new byte[1024];
            int legth = 0;
            try {
                out = httpServletResponse.getOutputStream();
                while ((legth = in.read(buf)) != -1) {
                    out.write(buf, 0, legth);
                }
            } finally {
                if (in != null) {
                    in.close();
                }
                if (out != null) {
                    out.close();
                }
            }
        } catch (Exception e) {
            log.error("生成流程图失败:{}", e, e.getStackTrace());
            throw new RuntimeException("生成流程图失败");
        }

    }

}
